/*
 * Copyright 2017 Red Hat, Inc.
 *
 * Red Hat licenses this file to you under the Apache License, version 2.0
 * (the "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package top.my.socket;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.NetSocket;
import io.vertx.core.parsetools.RecordParser;
import io.vertx.example.util.Runner;
import org.apache.log4j.Logger;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/*
 * @author Thomas Segismont
 */
public class SockServer extends AbstractVerticle {
    final Logger logger = Logger.getLogger(SockServer.class);
    ConcurrentHashMap<String, NetSocket> socketHolder = new ConcurrentHashMap<>();

    // Convenience method so you can run it in your IDE
    public static void main(String[] args) {
        Runner.runExample(SockServer.class);
    }

    @Override
    public void start() throws Exception {

        vertx.createNetServer().connectHandler(sock -> {
            logger.info("sock.sock(): " + sock.toString());
            logger.info("sock.localAddress(): " + sock.localAddress());
            logger.info("sock.remoteAddress(): " + sock.remoteAddress());
            RecordParser parser = RecordParser.newDelimited("\n", sock);
            parser.endHandler(v -> sock.close())
                    .exceptionHandler(t -> {
                        t.printStackTrace();
                        sock.close();
                    })
                    .handler(buffer -> {
                        String name = buffer.toString("UTF-8");
                        logger.info("client name: " + name);
                        JsonObject jsonObject = new JsonObject(name);
                        String id = jsonObject.getString("id");
                        String sendId = jsonObject.getString("sendId");
                        String message = jsonObject.getString("message");

                        logger.info("Net jsonObject id: " + jsonObject.getString("id"));
                        if (!socketHolder.containsValue(sock)) {
                            socketHolder.put(id, sock);
                        }
                        if (sendId != null && sendId.length() > 0) {
                            NetSocket sendSock = socketHolder.get(sendId);
                            if (sendSock != null) {
                                sendSock.write(message + "\n", "UTF-8");
                            }
                        }
                    });
            sock.closeHandler(close -> {
                logger.info("客户端退出连接");
                removeSocket(sock);
            });
        }).listen(1234).onSuccess(handler -> {
            logger.info("Socket服务器启动成功");
        }).onFailure(fail -> {
            logger.info("Socket服务器启动失败");
        });
    }

    private void removeSocket(NetSocket sock) {
        Iterator<Map.Entry<String, NetSocket>> it = socketHolder.entrySet().iterator();
        while (it.hasNext()) {
            if (it.next().getValue().equals(sock)) {
                it.remove();
                break;
            }
        }
    }
}
